package com.lihonghao.server;

import cn.hutool.core.thread.ThreadUtil;
import com.lihonghao.channel.HttpServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

//@Component
public class HttpServer implements ApplicationRunner {
    int port = 10088;

    public HttpServer() {
    }

    public HttpServer(int port) {
        this.port = port;
    }

    public void start() throws InterruptedException {
        int bossThreads = 4; // 建议Boss线程数为1-4，不宜超过CPU核心数
        int workerThreads = 8; // Worker线程数=CPU核心数*2
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup boss = new NioEventLoopGroup(bossThreads);
        EventLoopGroup work = new NioEventLoopGroup(workerThreads);
        bootstrap.group(boss, work)
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .channel(NioServerSocketChannel.class)
                .childHandler(new HttpServerInitializer());
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024 * 10); // 积压连接队列长度
        bootstrap.option(ChannelOption.SO_REUSEADDR , true);
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, false);// 启用 TCP Keep-Alive
        bootstrap.childOption(ChannelOption.TCP_NODELAY, true);// 禁用 Nagle 算法
        ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
        System.out.println("Server started on port " + port);
        ThreadUtil.execute(() -> {
            try {
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        HttpServer httpServer = new HttpServer();
        httpServer.start();
    }
}
